#include "../log/logger.hpp"
#include <iostream>
#include <thread>
#include <chrono>

/**
 * Sink配置示例
 * 演示如何配置不同类型的日志输出目标（Sink）
 */

using namespace tclog;

void demonstrateStdoutSink() {
    std::cout << "\n=== 标准输出Sink示例 ===" << std::endl;
    
    // 创建只输出到控制台的日志器
    LocalLoggerBuilder builder;
    builder.buildLoggerName("stdout_logger");
    builder.buildLoggerLevel(LogLevel::value::DEBUG);
    builder.buildSink<StdoutSink>();  // 添加标准输出Sink
    
    auto logger = builder.build();
    
    logger->debug(__FILE__, __LINE__, "这是标准输出的调试信息");
    logger->info(__FILE__, __LINE__, "这是标准输出的信息日志");
    logger->warn(__FILE__, __LINE__, "这是标准输出的警告信息");
}

void demonstrateFileSink() {
    std::cout << "\n=== 文件输出Sink示例 ===" << std::endl;
    
    // 创建输出到文件的日志器
    LocalLoggerBuilder builder;
    builder.buildLoggerName("file_logger");
    builder.buildLoggerLevel(LogLevel::value::DEBUG);
    builder.buildSink<FileSink>("./logs/example_file.log");  // 添加文件输出Sink
    
    auto logger = builder.build();
    
    logger->debug(__FILE__, __LINE__, "这是写入文件的调试信息");
    logger->info(__FILE__, __LINE__, "这是写入文件的信息日志");
    logger->warn(__FILE__, __LINE__, "这是写入文件的警告信息");
    logger->error(__FILE__, __LINE__, "这是写入文件的错误信息");
    
    std::cout << "日志已写入到 ./logs/example_file.log 文件中" << std::endl;
}

void demonstrateRollSink() {
    std::cout << "\n=== 滚动文件Sink示例 ===" << std::endl;
    
    // 创建滚动文件输出的日志器
    LocalLoggerBuilder builder;
    builder.buildLoggerName("roll_logger");
    builder.buildLoggerLevel(LogLevel::value::DEBUG);
    // 文件大小超过1KB时自动滚动到新文件
    builder.buildSink<RollSink>("./logs/roll_example-", 1024);
    
    auto logger = builder.build();
    
    // 写入大量日志以触发文件滚动
    for (int i = 1; i <= 50; ++i) {
        logger->info(__FILE__, __LINE__, "滚动文件日志第 %d 条，这是一条比较长的日志消息用于测试文件滚动功能", i);
    }
    
    std::cout << "滚动日志已写入到 ./logs/roll_example-*.log 文件中" << std::endl;
}

void demonstrateMultipleSinks() {
    std::cout << "\n=== 多Sink配置示例 ===" << std::endl;
    
    // 创建同时输出到控制台和文件的日志器
    LocalLoggerBuilder builder;
    builder.buildLoggerName("multi_sink_logger");
    builder.buildLoggerLevel(LogLevel::value::DEBUG);
    builder.buildSink<StdoutSink>();                        // 添加标准输出
    builder.buildSink<FileSink>("./logs/multi_sink.log");   // 添加文件输出
    builder.buildSink<RollSink>("./logs/multi_roll-", 512); // 添加滚动文件输出
    
    auto logger = builder.build();
    
    logger->debug(__FILE__, __LINE__, "多Sink调试信息 - 同时输出到控制台、文件和滚动文件");
    logger->info(__FILE__, __LINE__, "多Sink信息日志 - 可以在三个地方看到这条日志");
    logger->warn(__FILE__, __LINE__, "多Sink警告信息 - 灵活的输出配置");
    logger->error(__FILE__, __LINE__, "多Sink错误信息 - 确保重要日志不会丢失");
    
    std::cout << "日志已同时输出到控制台、./logs/multi_sink.log 和 ./logs/multi_roll-*.log" << std::endl;
}

void demonstrateDifferentLogLevels() {
    std::cout << "\n=== 不同日志级别的Sink配置示例 ===" << std::endl;
    
    // 创建只记录ERROR及以上级别的文件日志器
    LocalLoggerBuilder errorBuilder;
    errorBuilder.buildLoggerName("error_only_logger");
    errorBuilder.buildLoggerLevel(LogLevel::value::ERROR);  // 只记录ERROR及以上
    errorBuilder.buildSink<FileSink>("./logs/error_only.log");
    
    auto errorLogger = errorBuilder.build();
    
    // 创建记录所有级别的控制台日志器
    LocalLoggerBuilder allBuilder;
    allBuilder.buildLoggerName("all_levels_logger");
    allBuilder.buildLoggerLevel(LogLevel::value::DEBUG);    // 记录所有级别
    allBuilder.buildSink<StdoutSink>();
    
    auto allLogger = allBuilder.build();
    
    // 测试不同级别的日志
    std::cout << "错误日志器测试（只有ERROR和FATAL会被记录到文件）：" << std::endl;
    errorLogger->debug(__FILE__, __LINE__, "这条DEBUG不会被记录");
    errorLogger->info(__FILE__, __LINE__, "这条INFO不会被记录");
    errorLogger->warn(__FILE__, __LINE__, "这条WARN不会被记录");
    errorLogger->error(__FILE__, __LINE__, "这条ERROR会被记录到文件");
    errorLogger->fatal(__FILE__, __LINE__, "这条FATAL会被记录到文件");
    
    std::cout << "\n全级别日志器测试（所有级别都会输出到控制台）：" << std::endl;
    allLogger->debug(__FILE__, __LINE__, "控制台DEBUG信息");
    allLogger->info(__FILE__, __LINE__, "控制台INFO信息");
    allLogger->warn(__FILE__, __LINE__, "控制台WARN信息");
    allLogger->error(__FILE__, __LINE__, "控制台ERROR信息");
    allLogger->fatal(__FILE__, __LINE__, "控制台FATAL信息");
}

void demonstrateCustomFormatter() {
    std::cout << "\n=== 自定义格式化器的Sink配置示例 ===" << std::endl;
    
    // 创建带自定义格式的日志器
    LocalLoggerBuilder builder;
    builder.buildLoggerName("custom_format_logger");
    builder.buildLoggerLevel(LogLevel::value::DEBUG);
    // 自定义日志格式：时间 [级别] 消息
    builder.buildFormatter("[%d{%Y-%m-%d %H:%M:%S}] [%p] %m%n");
    builder.buildSink<StdoutSink>();
    builder.buildSink<FileSink>("./logs/custom_format.log");
    
    auto logger = builder.build();
    
    logger->debug(__FILE__, __LINE__, "自定义格式的调试信息");
    logger->info(__FILE__, __LINE__, "自定义格式的信息日志");
    logger->warn(__FILE__, __LINE__, "自定义格式的警告信息");
    
    std::cout << "自定义格式的日志已输出到控制台和 ./logs/custom_format.log" << std::endl;
}

int main() {
    std::cout << "=== BoltLog Sink配置示例 ===" << std::endl;
    
    // 演示各种Sink配置
    demonstrateStdoutSink();
    demonstrateFileSink();
    demonstrateRollSink();
    demonstrateMultipleSinks();
    demonstrateDifferentLogLevels();
    demonstrateCustomFormatter();
    
    std::cout << "\n=== Sink配置示例完成 ===" << std::endl;
    std::cout << "请检查 ./logs/ 目录下生成的日志文件" << std::endl;
    
    return 0;
}